package errors

import (
	"fmt"
)

type Error struct {
	code   int
	args   []string
	reason string
}

func New(code int, reason string, args ...interface{}) (err *Error) {
	result := new(Error)
	result.code = code
	if len(args) > 0 {
		reason = fmt.Sprintf(reason, args...)

		type iString interface {
			String() string
		}
		for _, arg := range args {
			switch arg.(type) {
			case string:
				result.args = append(result.args, arg.(string))
			case iString:
				result.args = append(result.args, arg.(iString).String())
			default:
				result.args = append(result.args, fmt.Sprintf("%v", arg))
			}
		}
	}
	result.reason = reason

	return result
}

func (err *Error) Code() (result int) {
	if err != nil {
		result = err.code
	}

	return result
}

func (err *Error) Args() []string {
	return err.args
}

func (err *Error) String() string {
	result := ""
	if err != nil {
		result = err.reason
	}

	return result
}

func (err *Error) Parse() (results []interface{}) {
	if err.code != 0 {
		results = append(results, err.code)
		results = append(results, err.args)
	}

	return
}

func (err *Error) Error() string {
	return err.String()
}
